home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP10.ZIP / CHAP10 / SCHMOO / IDATAOBJ.CPP < prev    next >
C/C++ Source or Header  |  1993-06-13  |  9KB  |  357 lines

  1. /*
  2.  * IDATAOBJ.CPP
  3.  * Schmoo Server Chapter 10
  4.  *
  5.  * Implementation of the IDataObject interface.
  6.  *
  7.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Software Design Engineer
  10.  * Microsoft Systems Developer Relations
  11.  *
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17. #include "schmoo.h"
  18.  
  19.  
  20. /*
  21.  * CImpIDataObject::CImpIDataObject
  22.  * CImpIDataObject::~CImpIDataObject
  23.  *
  24.  * Parameters (Constructor):
  25.  *  pObj            LPVOID of the object we're in.
  26.  *  punkOuter       LPUNKNOWN to which we delegate.
  27.  */
  28.  
  29. CImpIDataObject::CImpIDataObject(LPCFigure pObj, LPUNKNOWN punkOuter)
  30.     {
  31.     m_cRef=0;
  32.     m_pObj=pObj;
  33.     m_punkOuter=punkOuter;
  34.     return;
  35.     }
  36.  
  37. CImpIDataObject::~CImpIDataObject(void)
  38.     {
  39.     return;
  40.     }
  41.  
  42.  
  43.  
  44.  
  45. /*
  46.  * CImpIDataObject::QueryInterface
  47.  * CImpIDataObject::AddRef
  48.  * CImpIDataObject::Release
  49.  *
  50.  * Purpose:
  51.  *  IUnknown members for CImpIDataObject object.
  52.  */
  53.  
  54. STDMETHODIMP CImpIDataObject::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  55.     {
  56.     return m_punkOuter->QueryInterface(riid, ppv);
  57.     }
  58.  
  59.  
  60. STDMETHODIMP_(ULONG) CImpIDataObject::AddRef(void)
  61.     {
  62.     ++m_cRef;
  63.     return m_punkOuter->AddRef();
  64.     }
  65.  
  66. STDMETHODIMP_(ULONG) CImpIDataObject::Release(void)
  67.     {
  68.     --m_cRef;
  69.     return m_punkOuter->Release();
  70.     }
  71.  
  72.  
  73.  
  74.  
  75.  
  76. /*
  77.  * CImpIDataObject::GetData
  78.  *
  79.  * Purpose:
  80.  *  Retrieves data described by a specific FormatEtc into a StgMedium
  81.  *  allocated by this function.  Used like GetClipboardData.
  82.  *
  83.  * Parameters:
  84.  *  pFE             LPFORMATETC describing the desired data.
  85.  *  pSTM            LPSTGMEDIUM in which to return the data.
  86.  *
  87.  * Return Value:
  88.  *  HRESULT         NOERROR on success, error code otherwise.
  89.  */
  90.  
  91. STDMETHODIMP CImpIDataObject::GetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
  92.     {
  93.     UINT            cf=pFE->cfFormat;
  94.     BOOL            fRet=FALSE;
  95.  
  96.     //Another part of us already knows if the format is good.
  97.     if (NOERROR!=QueryGetData(pFE))
  98.         return ResultFromScode(DATA_E_FORMATETC);
  99.  
  100.     if (CF_METAFILEPICT==cf || CF_BITMAP==cf || m_pObj->m_cf==cf)
  101.         {
  102.         if (CF_METAFILEPICT==cf)
  103.             {
  104.             pSTM->tymed=TYMED_MFPICT;
  105.             }
  106.         else
  107.             pSTM->tymed=TYMED_HGLOBAL;
  108.  
  109.         pSTM->pUnkForRelease=NULL;
  110.         pSTM->hGlobal=m_pObj->m_pDoc->RenderFormat(cf);
  111.         fRet=(NULL!=pSTM->hGlobal);
  112.         }
  113.     else
  114.         fRet=m_pObj->m_pDoc->FRenderMedium(cf, pSTM);
  115.  
  116.     return fRet ? NOERROR : ResultFromScode(DATA_E_FORMATETC);
  117.     }
  118.  
  119.  
  120.  
  121.  
  122. /*
  123.  * CImpIDataObject::GetDataHere
  124.  *
  125.  * Purpose:
  126.  *  Renders the specific FormatEtc into caller-allocated medium
  127.  *  provided in pSTM.
  128.  *
  129.  * Parameters:
  130.  *  pFE             LPFORMATETC describing the desired data.
  131.  *  pSTM            LPSTGMEDIUM providing the medium into which
  132.  *                  wer render the data.
  133.  *
  134.  * Return Value:
  135.  *  HRESULT         NOERROR on success, error code otherwise.
  136.  */
  137.  
  138. STDMETHODIMP CImpIDataObject::GetDataHere(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
  139.     {
  140.     UINT        cf;
  141.     LONG        lRet;
  142.  
  143.     /*
  144.      * The only reasonable time this is called is for CF_EMBEDSOURCE
  145.      * and TYMED_ISTORAGE (and later for CF_LINKSOURCE).  This means
  146.      * the same as IPersistStorage::Save.
  147.      */
  148.  
  149.     cf=RegisterClipboardFormat(CF_EMBEDSOURCE);
  150.  
  151.     //Aspect is unimportant to us here, as is lindex and ptd.
  152.     if (cf==pFE->cfFormat && (TYMED_ISTORAGE & pFE->tymed))
  153.         {
  154.         //We have an IStorage we can write into.
  155.         pSTM->tymed=TYMED_ISTORAGE;
  156.         pSTM->pUnkForRelease=NULL;
  157.         lRet=m_pObj->m_pPL->WriteToStorage(pSTM->pstg, VERSIONCURRENT);
  158.  
  159.         if (lRet >= 0)
  160.             return NOERROR;
  161.  
  162.         return ResultFromScode(STG_E_WRITEFAULT);
  163.         }
  164.  
  165.     return ResultFromScode(DATA_E_FORMATETC);
  166.     }
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173. /*
  174.  * CImpIDataObject::QueryGetData
  175.  *
  176.  * Purpose:
  177.  *  Tests if a call to ::GetData with this FormatEtc will provide
  178.  *  any rendering; used like IsClipboardFormatAvailable.
  179.  *
  180.  * Parameters:
  181.  *  pFE             LPFORMATETC describing the desired data.
  182.  *
  183.  * Return Value:
  184.  *  HRESULT         NOERROR on success, error code otherwise.
  185.  */
  186.  
  187. STDMETHODIMP CImpIDataObject::QueryGetData(LPFORMATETC pFE)
  188.     {
  189.     UINT            cf=pFE->cfFormat;
  190.     UINT            i;
  191.  
  192.     //Check the aspects we support.
  193.     if (!(DVASPECT_CONTENT & pFE->dwAspect))
  194.         return ResultFromScode(S_FALSE);
  195.  
  196.     for (i=0; i < m_pObj->m_cfeGet; i++)
  197.         {
  198.         if (pFE->cfFormat==m_pObj->m_rgfeGet[i].cfFormat
  199.             && pFE->tymed & m_pObj->m_rgfeGet[i].tymed)
  200.             {
  201.             return NOERROR;
  202.             }
  203.         }
  204.  
  205.     return ResultFromScode(S_FALSE);
  206.     }
  207.  
  208.  
  209.  
  210.  
  211.  
  212. /*
  213.  * CImpIDataObject::GetCanonicalFormatEtc
  214.  *
  215.  * Purpose:
  216.  *  Provides the caller with an equivalent FormatEtc to the one
  217.  *  provided when different FormatEtcs will produce exactly the
  218.  *  same renderings.
  219.  *
  220.  * Parameters:
  221.  *  pFEIn            LPFORMATETC of the first description.
  222.  *  pFEOut           LPFORMATETC of the equal description.
  223.  *
  224.  * Return Value:
  225.  *  HRESULT         NOERROR on success, error code otherwise.
  226.  */
  227.  
  228. STDMETHODIMP CImpIDataObject::GetCanonicalFormatEtc(LPFORMATETC pFEIn
  229.     , LPFORMATETC pFEOut)
  230.     {
  231.     return ResultFromScode(DATA_S_SAMEFORMATETC);
  232.     }
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239. /*
  240.  * CImpIDataObject::SetData
  241.  *
  242.  * Purpose:
  243.  *  Places data described by a FormatEtc and living in a StgMedium
  244.  *  into the object.  The object may be responsible to clean up the
  245.  *  StgMedium before exiting.
  246.  *
  247.  * Parameters:
  248.  *  pFE             LPFORMATETC describing the data to set.
  249.  *  pSTM            LPSTGMEDIUM containing the data.
  250.  *  fRelease        BOOL indicating if this function is responsible for
  251.  *                  freeing the data.
  252.  *
  253.  * Return Value:
  254.  *  HRESULT         NOERROR on success, error code otherwise.
  255.  */
  256.  
  257. STDMETHODIMP CImpIDataObject::SetData(LPFORMATETC pFE, STGMEDIUM FAR *pSTM
  258.     , BOOL fRelease)
  259.     {
  260.     LONG            lRet;
  261.  
  262.     /*
  263.      * Data can only come from global memory containing a POLYLINEDATA
  264.      * structure that we send to the Polyline's DataSetMem.
  265.      */
  266.     if ((pFE->cfFormat!=m_pObj->m_cf) || !(DVASPECT_CONTENT & pFE->dwAspect)
  267.         || (TYMED_HGLOBAL!=pSTM->tymed))
  268.         return ResultFromScode(DATA_E_FORMATETC);
  269.  
  270.     lRet=m_pObj->m_pPL->DataSetMem(pSTM->hGlobal, FALSE, TRUE, TRUE);
  271.  
  272.     if (fRelease)
  273.         ReleaseStgMedium(pSTM);
  274.  
  275.     return (POLYLINE_E_NONE==lRet) ?
  276.         NOERROR : ResultFromScode(DATA_E_FORMATETC);
  277.     }
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284. /*
  285.  * CImpIDataObject::EnumFormatEtc
  286.  *
  287.  * Purpose:
  288.  *  Returns an IEnumFORMATETC object through which the caller can iterate
  289.  *  to learn about all the data formats this object can provide through
  290.  *  either ::GetData[Here] or ::SetData.
  291.  *
  292.  * Parameters:
  293.  *  dwDir           DWORD describing a data direction, either DATADIR_SET
  294.  *                  or DATADIR_GET.
  295.  *  ppEnum          LPENUMFORMATETC FAR * in which to return the pointer
  296.  *                  to the enumerator.
  297.  *
  298.  * Return Value:
  299.  *  HRESULT         NOERROR on success, error code otherwise.
  300.  */
  301.  
  302. STDMETHODIMP CImpIDataObject::EnumFormatEtc(DWORD dwDir
  303.     , LPENUMFORMATETC FAR *ppEnum)
  304.     {
  305.     return ResultFromScode(OLE_S_USEREG);
  306.     }
  307.  
  308.  
  309.  
  310.  
  311.  
  312. /*
  313.  * CImpIDataObject::DAdvise
  314.  * CImpIDataObject::DUnadvise
  315.  * CImpIDataObject::EnumDAdvise
  316.  *
  317.  * Pass-throughs to IDataAdviseHolder.
  318.  */
  319.  
  320. STDMETHODIMP CImpIDataObject::DAdvise(LPFORMATETC pFE, DWORD dwFlags
  321.     , LPADVISESINK pIAdviseSink, LPDWORD pdwConn)
  322.     {
  323.     HRESULT         hr;
  324.  
  325.     if (NULL==m_pObj->m_pIDataAdviseHolder)
  326.         {
  327.         hr=CreateDataAdviseHolder(&m_pObj->m_pIDataAdviseHolder);
  328.  
  329.         if (FAILED(hr))
  330.             return ResultFromScode(E_OUTOFMEMORY);
  331.         }
  332.  
  333.     hr=m_pObj->m_pIDataAdviseHolder->Advise((LPDATAOBJECT)this, pFE
  334.         , dwFlags, pIAdviseSink, pdwConn);
  335.  
  336.     return hr;
  337.     }
  338.  
  339.  
  340. STDMETHODIMP CImpIDataObject::DUnadvise(DWORD dwConn)
  341.     {
  342.     if (NULL==m_pObj->m_pIDataAdviseHolder)
  343.         return ResultFromScode(E_FAIL);
  344.  
  345.     return m_pObj->m_pIDataAdviseHolder->Unadvise(dwConn);
  346.     }
  347.  
  348.  
  349.  
  350. STDMETHODIMP CImpIDataObject::EnumDAdvise(LPENUMSTATDATA FAR *ppEnum)
  351.     {
  352.     if (NULL==m_pObj->m_pIDataAdviseHolder)
  353.         return ResultFromScode(E_FAIL);
  354.  
  355.     return m_pObj->m_pIDataAdviseHolder->EnumAdvise(ppEnum);
  356.     }
  357.